using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using MySql.Data.MySqlClient;
namespace Jasongozy.Copor {
    public class TemplateParameter {
        #region Property&Fields


        Dictionary<string, string> sampleParams = new Dictionary<string, string>();

        public Dictionary<string, string> SampleParams {
            get { return sampleParams; }
            set { sampleParams = value; }
        }
        Dictionary<string, string[]> complexParams = new Dictionary<string, string[]>();

        public Dictionary<string, string[]> ComplexParams {
            get { return complexParams; }
            set { complexParams = value; }
        }

        Dictionary<string, Dictionary<string, string>> specialParams = new Dictionary<string, Dictionary<string, string>>();

        public Dictionary<string, Dictionary<string, string>> SpecialParams {
            get { return specialParams; }
            set { specialParams = value; }
        }

        Dictionary<string, Dictionary<string, List<string>>> specialAryParams = new Dictionary<string, Dictionary<string, List<string>>>();

        public Dictionary<string, Dictionary<string, List<string>>> SpecialAryParams {
            get { return specialAryParams; }
            set { specialAryParams = value; }
        }


        #endregion

        private TemplateParameter() {
        }

        static TemplateParameter _Instance;

        public static TemplateParameter Instance {
            get {
                if (_Instance == null) {
                    throw new NullReferenceException("Please Init it at first!");
                }
                return _Instance;
            }
        }

        public static void InitTemplateParameter(TableSchema schame, string connectionStr, string dbName, string lang, string dbType, string sqlType) {
            TemplateParameter param = new TemplateParameter();
           
            param.SampleParams["ConnectionStr"] = connectionStr;
            param.SampleParams["DbName"] = dbName;
            param.SampleParams["Language"] = lang;
            param.SampleParams["DbType"] = dbType;
            param.SampleParams["SqlType"] = sqlType;
            if (schame != null) {
                Type schameType = typeof(TableSchema);
                foreach (FieldInfo finfo in schameType.GetFields()) {
                    if (!finfo.IsPublic) continue;
                    object v = finfo.GetValue(schame);
                    Type vT = finfo.FieldType;
                    if (vT == typeof(string[])) {
                        param.ComplexParams[finfo.Name] = v != null ? (string[])v : null;
                    } else if (vT == typeof(string)) {
                        param.SampleParams[finfo.Name] = v != null ? (string)v : null;
                    } else if (vT == typeof(Dictionary<string, string>)) {
                        param.SpecialParams[finfo.Name] = v != null ? (Dictionary<string, string>)v : null;
                    }
                }
            }
            _Instance = param;
        }

        public void AddMySqlProcParams(MySqlProcSchema schema) {
            //MySqlProcParams mysqlParam = new MySqlProcParams();
            if (!specialAryParams.ContainsKey(schema.ProcName)) {
                specialAryParams[schema.ProcName] = new Dictionary<string, List<string>>();

                foreach (MySqlParameter p in schema.Params) {
                    Type t = p.GetType();
                    foreach (PropertyInfo pro in t.GetProperties()) {
                        if (pro.CanRead && pro.PropertyType != typeof(object) && pro.PropertyType != typeof(bool) && pro.PropertyType != typeof(System.Data.DataRowVersion)) {
                            if (!specialAryParams[schema.ProcName].ContainsKey(pro.Name)) {
                                specialAryParams[schema.ProcName][pro.Name] = new List<string>();
                            }

                            object o = pro.GetValue(p, null);
                            specialAryParams[schema.ProcName][pro.Name].Add(o != null ? o.ToString() : null);

                        }
                    }
                }
            }

        }

        public string DisplayProcParams(string procName) {
            StringBuilder code = new StringBuilder();
            code.Append("procName: ");
            code.AppendLine(procName);
            foreach (KeyValuePair<string, List<string>> p in specialAryParams[procName]) {
                //code.Append(p.Key);
                //code.AppendLine(":       ");
                code.AppendLine(p.Key);
                int index = 0;
                foreach (string s in p.Value) {

                    code.Append(specialAryParams[procName]["ParameterName"][index]);
                    code.Append(":\t");
                    code.AppendLine(s);
                    index++;
                }
            }
            return code.ToString();
        }
    }
}
